/*
 *  session_dispatcher.cpp
 */

#include <string>
#include <vector>
#include "../../common/src/debug.h"
#include "../../common/src/lock.h"
#include "../../common/src/message_queue.h"
#include "../../common/src/protocol.h"
#include "../../common/src/session.h"
#include "../../common/src/synchro_list.h"
#include "../../common/src/socket.h"
#include "../../common/src/socket_exception.h"
#include "../../common/src/util.h"
#include "server_app.h"
#include "session_dispatcher.h"

SessionDispatcher::SessionDispatcher(ServerApp* app, Socket* sock) {
    this->app = app;
    this->sock = sock;
    try {
        sock->bind();
        sock->listen(LISTEN_BACKLOG);
    } catch (SocketException& e) {
        PRINT("[!] connect() triggered an exception.");
        if (sock != NULL) delete sock;
        throw;
    }
}

SessionDispatcher::~SessionDispatcher() {
    delete sock;
}

void SessionDispatcher::run() {
    Session* session;
    Socket* client_sock;
    try {
        while (app->getRunning()) {
            client_sock = sock->accept();
            session = new Session(SessionDispatcher::nextID(),
                                  client_sock,
                                  app->getMessageQueue());
            Message* msg = new Message(session->getID(), Protocol::MSG_INFO);
            std::string info[6];
            Lock campaigns_lock(app->getCampaigns().getMutex());
            std::vector<Campaign*>* v = app->getCampaigns().getVector();
            Campaign* campaign;
            for (int i = 0; i < v->size(); i++) {
                campaign = (*v)[i];
                info[0] = Util::itos(campaign->getID());
                info[1] = campaign->getName();
                info[2] = Util::itos(campaign->getDifficulty());
                info[3] = Util::itos(campaign->getMinPlayers());
                info[4] = Util::itos(campaign->getLevelsSize());
                info[5] = "imageID";//Util::itos(campaign->getImage()->getID());
                msg->addRecord(info, 6);
            }

            session->sendMessage(msg);
            Lock sessions_lock(app->getSessions().getMutex());
            app->getSessions().getList()->push_back(session);
        }
    } catch(...) {
        PRINT("[!] Receiver accept() triggered an exception.");
    }
}

int SessionDispatcher::id = 0;

std::string SessionDispatcher::nextID() {
    return "session:" + Util::itos(++(SessionDispatcher::id));
}

//{+}

